import java.util.Random;
import java.util.Stack;

/**
 * class TileSet is the working Draw pile for the game 24/7.  It stores both
 * the tiles that are in the game and the working draw pile.  The draw pile is
 * randomized using the Fischer-Yates algorithm.
 * 
 * @author Darren Couch
 * @version 1.0
 */
public class TileSet
{
	//variables
	int[] p_tilesArray = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
	Stack<Integer> p_shuffledTiles = new Stack<Integer>();
	final int PILE_OFFSET = 3;
	
	/**
	 * The constructor for TileSet builds a pre-shuffled "draw pile" for use in 
	 * a game of 24/7.
	 */
	public TileSet()
	{
		p_shuffledTiles = shuffle(p_tilesArray);
	}
	
	/**
	 * shuffle applies the Fischer-Yates algorithm to the tile set to create
	 * a working draw pile.
	 * @param int[] tilesArray
	 * @return Stack<Integer> shuffleDeck
	 */
	private Stack<Integer> shuffle(int[] tilesArray)
	{
		//local variables
		Stack<Integer> shuffleDeck = new Stack<Integer>();
		Random rand = new Random();
		int workingSet = tilesArray.length;
		int fisherYatesSwap = 0;
		
		//create a random number from the workingSet, then push the integer at
		//that location onto the stack.
		while(workingSet > 0)
		{
			fisherYatesSwap = rand.nextInt(workingSet);
			workingSet--;
			int tmp = tilesArray[workingSet];
			tilesArray[workingSet] = tilesArray[fisherYatesSwap];
			tilesArray[fisherYatesSwap] = tmp;
		}
		
		// this loop pushes sorted values of the correct number (total size of
		// tile set - the number of tiles to be taken out before play) of tiles
		// onto the stack to be returned.
		for(int i = 0; i < tilesArray.length - PILE_OFFSET; i++)
		{
			shuffleDeck.push(tilesArray[i]);
		}
		
		return shuffleDeck;
	}

	/**
	 * getTile "draws" a tile from the draw pile.
	 * @return int tileToGet or -1 if there are no more tiles.
	 */
	public int getTile()
	{
		int tileToGet = -1;
		
		if(p_shuffledTiles.size() > 0)
		{
			tileToGet = p_shuffledTiles.pop();
		}
		
		return tileToGet;
	}
	
	/**
	 * pileSize returns the amount of tiles left in the draw pile
	 * @return int size of pile
	 */
	public int pileSize()
	{
		return p_shuffledTiles.size();
	}
	
}
